package com.chezai.client.utils;

import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;

import com.chezai.client.bean.SpeechInitEvent;
import com.chezai.client.global.TerminalApplication;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SynthesizerListener;
import com.orhanobut.logger.Logger;

import org.greenrobot.eventbus.EventBus;

import java.io.File;

/**
 * 语音合成工具类
 * Created by likunyang on 2017/9/21.
 */

public class SpeechUtils implements SynthesizerListener, InitListener, SoundPool.OnLoadCompleteListener {
    private static SpeechUtils newInstance;
    private SoundPool mSoundPool;
    private SpeechSynthesizer mTts;
    private String TAG = this.getClass().getSimpleName();
    private SynthesizerListener mSynListener;
    private boolean isInitSucess;
    private int initErrorCode;

    private SpeechUtils() {
        //1.创建 SpeechSynthesizer 对象, 第二个参数：本地合成时传 InitListener
        mTts = SpeechSynthesizer.createSynthesizer(TerminalApplication.mContext, this);
        mSoundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
        mSoundPool.setOnLoadCompleteListener(this);
    }

    public static SpeechUtils getInstance() {
        if (newInstance == null) {
            newInstance = new SpeechUtils();
        }
        return newInstance;
    }

    /**
     * 练车抓拍 三秒倒数
     */
    public static String getStudentCountDownVideoPath() {
        return SDCardUtil.getVoiceDir() + "countdown_three_second.wav";
    }

    public static String getTakePhotoSucessPath() {
        return SDCardUtil.getVoiceDir() + "take_photo_sucess.wav";
    }

    public static String getVideoTempPath() {
        return SDCardUtil.getVoiceTempDir() + DateUtil.timestampStr(DateUtil.sf19) + ".wav";
    }

    // 驶出围栏提示语
    public static String getDriveOutFencePath() {
        return SDCardUtil.getVoiceDir() + "driveOutFence.wav";
    }

    // 设备定位长时无效
    public static String getLocInvalid() {
        return SDCardUtil.getVoiceDir() + "locInvalid.wav";
    }

    // 驶出围栏提示语
    public static String getDriveInFencePath() {
        return SDCardUtil.getVoiceDir() + "driveInFence.wav";
    }

    /**
     * 科一科四 超四小时提示语音
     */
    public static String getTimeOutFourHourAlert() {
        return SDCardUtil.getVoiceDir() + "timeOutFourHour.wav";
    }

    /**
     * 科一科四 超四小时提示语音
     */
    public static String getTimeOutFiveHourAlert() {
        return SDCardUtil.getVoiceDir() + "timeOutFiveHour.wav";
    }

    /**
     * 抓拍三秒倒计时提示
     */
    public static String getThreeCountTakePhotoPath() {
        return SDCardUtil.getVoiceDir() + "three_second_count_hint.wav";
    }

    public void setSynListener(SynthesizerListener listener) {
        this.mSynListener = listener;
    }

    private void setParam(String soundSourcePath) {
        mTts.setParameter(SpeechConstant.PARAMS, null);
        // 根据合成引擎设置相应参数
        mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
        // 设置在线合成发音人
        mTts.setParameter(SpeechConstant.VOICE_NAME, "nannan");
        //设置合成语速
        mTts.setParameter(SpeechConstant.SPEED, "50");
        //设置合成音调
        mTts.setParameter(SpeechConstant.PITCH, "50");
        //设置合成音量
        mTts.setParameter(SpeechConstant.VOLUME, "80");
        //设置播放器音频流类型
        mTts.setParameter(SpeechConstant.STREAM_TYPE, "3");
        // 设置播放合成音频打断音乐播放，默认为true
        mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true");
        // 设置音频保存路径，保存音频格式支持pcm、wav，设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
        // 注：AUDIO_FORMAT参数语记需要更新版本才能生效
        mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
        mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, soundSourcePath);
    }

    /**
     * 播放或合成语音
     *
     * @param msg
     * @param filePath
     * @return
     */
    public int playOrComposed(String msg, String filePath) {
        Logger.t(TAG).d("play sound msg " + msg);
        int code = playSound(filePath);
        if (code == -1) {
            code = composedSound(msg, filePath);
        }
        return code;
    }

    /**
     * 播放语音
     *
     * @param filePath 需转换的字符串
     */

    public int playSound(String filePath) {
        int code = 0;
        //如果语音文件存在
        if (new File(filePath).exists()) {
            final int soundID = mSoundPool.load(filePath, 1);
        } else {
            code = -1;
        }
        return code;
    }

    @Override
    public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
        mSoundPool.play(sampleId, 1, 1, 0, 0, 1);
    }

    /**
     * 合成语音
     *
     * @param msg
     * @param filePath
     * @return
     */
    public int composedSound(String msg, String filePath) {
        setParam(filePath);
        int code = mTts.startSpeaking(msg, mSynListener == null ? this : mSynListener);
        return code;
    }


    @Override
    public void onSpeakBegin() {
        Logger.t(TAG).d("onSpeakBegin");
    }

    @Override
    public void onBufferProgress(int i, int i1, int i2, String s) {
        Logger.t(TAG).d("onBufferProgress");
    }

    @Override
    public void onSpeakPaused() {
        Logger.t(TAG).d("onSpeakPaused");
    }

    @Override
    public void onSpeakResumed() {
        Logger.t(TAG).d("onSpeakResumed");
    }

    @Override
    public void onSpeakProgress(int i, int i1, int i2) {

    }

    @Override
    public void onCompleted(SpeechError speechError) {
        Logger.t(TAG).d("onCompleted  code:" + speechError.getErrorCode() + "    des:" + speechError.getErrorDescription());
    }

    @Override
    public void onEvent(int i, int i1, int i2, Bundle bundle) {
        Logger.t(TAG).d("onEvent");
    }

    @Override
    public void onInit(int code) {
        if (code != ErrorCode.SUCCESS) {
            isInitSucess = false;
            initErrorCode = code;
            ToastUtil.showLongToast(TerminalApplication.mContext, "初始化失败,错误码：" + code);
        } else {
            isInitSucess = true;
            // 初始化成功，之后可以调用startSpeaking方法
            // 注：有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成，
            // 正确的做法是将onCreate中的startSpeaking调用移至这里
        }
        EventBus.getDefault().post(new SpeechInitEvent(isInitSucess, initErrorCode));
    }

    public boolean isInitSucess() {
        return isInitSucess;
    }

    public int getInitErrorCode() {
        return initErrorCode;
    }

    public void reset() {
        if (mTts != null) {
            mTts.stopSpeaking();
            mTts.destroy();
        }
        newInstance = new SpeechUtils();
    }
}
